/********************************************
 * 功能说明: 
 * 模块名称: 
 * 系统名称: 
 * 软件版权: Frank
 * 系统版本: 1.0.0
 * 开发人员: Frank
 * 开发时间: 2019/12/18 11:31
 * 审核人员: 
 * 相关文档: 
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.spring.arch.uaa.web.controller;

import com.codahale.metrics.annotation.Timed;
import com.google.common.collect.Lists;
import com.spring.arch.common.dto.result.ListResultDTO;
import com.spring.arch.common.security.CurrentUserContextHolder;
import com.spring.arch.common.security.UserPrincipal;
import com.spring.arch.uaa.enums.OrganizationType;
import com.spring.arch.uaa.errorcode.UaaErrorCode;
import com.spring.arch.uaa.web.dto.WebDepartmentDTO;
import com.spring.arch.uaa.web.dto.WebOrganizationDTO;
import com.spring.arch.uaa.web.dto.WebUserForListDTO;
import com.spring.arch.common.dto.result.ListResultDTO;
import com.spring.arch.common.exception.ExceptionHolder;
import com.spring.arch.common.security.CurrentUserContextHolder;
import com.spring.arch.common.security.UserPrincipal;
import com.spring.arch.uaa.enums.Constant;
import com.spring.arch.uaa.enums.OrganizationType;
import com.spring.arch.uaa.model.Organization;
import com.spring.arch.uaa.model.OrganizationEmployeeRole;
import com.spring.arch.uaa.model.Project;
import com.spring.arch.uaa.repository.OrganizationEmployeeRoleRepository;
import com.spring.arch.uaa.repository.OrganizationRepository;
import com.spring.arch.uaa.repository.ProjectRepository;
import com.spring.arch.uaa.service.OrganizationService;
import com.spring.arch.uaa.web.converter.WebDepartmentConverter;
import com.spring.arch.uaa.web.converter.WebOrganizationConverter;
import com.spring.arch.uaa.web.converter.WebUserForListConverter;
import com.spring.arch.uaa.web.dto.WebDepartmentDTO;
import com.spring.arch.uaa.web.dto.WebOrganizationDTO;
import com.spring.arch.uaa.web.dto.WebUserForListDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import static com.spring.arch.uaa.errorcode.UaaErrorCode.E2001003001;

/**
 * 物业调用Api
 *
 * @author Frank
 * @version 1.0.0.1
 * @since 2019/12/18 11:31
 */
@Slf4j
@RestController
@RequestMapping(value = "/system", produces = MediaType.APPLICATION_JSON_VALUE)
@Api(tags = {"物业调用Api"}, produces = MediaType.APPLICATION_JSON_VALUE, protocols = "http, https")
public class EstateController {

    @Autowired
    private OrganizationRepository organizationRepository;

    @Autowired
    private ProjectRepository projectRepository;

    @Autowired
    private OrganizationEmployeeRoleRepository organizationEmployeeRoleRepository;

    @Autowired
    private WebUserForListConverter userForListConverter;

    @Autowired
    private WebDepartmentConverter departmentConverter;

    @Autowired
    private WebOrganizationConverter webOrganizationConverter;

    @Autowired
    private OrganizationService organizationService;

    /**
     * 获取部门下的用户列表（员工）
     */
    @Timed
    @ApiOperation(value = "获取部门下的员工列表")
    @GetMapping(value = "/w/user/employee")
    public ListResultDTO<WebUserForListDTO> searchDepartmentEmployee(@RequestParam(required = false) UUID departmentId) {

        if(departmentId == null) {

            UserPrincipal user = CurrentUserContextHolder.getCurrentUser();
            departmentId = user.getOrgId();
        }

        Organization organization = organizationRepository.findById(departmentId)
                .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001003001, Project.class.getSimpleName()));

        // 获取子组织
        List<Organization> organizations = organizationService.getChildrenOrganization(organization);
        organizations.add(organization);

        // 排除领导
        List<OrganizationEmployeeRole> organizationEmployeeRoles =
                organizationEmployeeRoleRepository.findByOrganizationInAndOrganizationDisableFalseAndRoleCodeIsNotIn(
                        organizations, Constant.MANAGER_ROLE_CODES);

        return ListResultDTO.success(userForListConverter.toListDTO(organizationEmployeeRoles.stream()
                .map(l -> l.getOrganizationEmployee().getUser()).collect(Collectors.toSet())));
    }

    /**
     * 获取部门树
     */
    @Timed
    @ApiOperation(value = "获取项目的部门和员工树")
    @GetMapping(value = "/w/organization/department")
    public ListResultDTO<WebDepartmentDTO> searchDepartmentWeb(@RequestHeader(value = "clientId") UUID projectId) {
        Project project = projectRepository.findById(projectId).get();
        Organization organization = project.getRootOrganization();
        final WebDepartmentDTO department = this.departmentConverter.toTreeDTO(organization);
        return ListResultDTO.success(Lists.newArrayList(department));
    }


    /**
     * 获取项目的全部部门
     */
    @Timed
    @ApiOperation(value = "获取项目的全部部门")
    @PostMapping(value = "/w/organization/s")
    public ListResultDTO<WebOrganizationDTO> searchAllDepartment(@RequestHeader(value = "clientId") UUID projectId) {
        List<Organization> organizations =
                organizationRepository.findAllByProjectIdAndTypeAndDisableFalse(projectId,
                        OrganizationType.FUNCTION);
        return this.webOrganizationConverter.toResultDTO(organizations);
    }


    /**
     * 获取项目的全部部门
     */
    @Timed
    @ApiOperation(value = "获取项目的全部部门")
    @PostMapping(value = "/m/organization")
    public ListResultDTO<WebOrganizationDTO> searchAllDepartmentForMobile(@RequestHeader(value = "clientId") UUID projectId) {
        List<Organization> organizations =
                organizationRepository.findAllByProjectIdAndTypeAndDisableFalse(projectId,
                        OrganizationType.FUNCTION);
        return this.webOrganizationConverter.toResultDTO(organizations);
    }


    /**
     * 获取部门树
     */
    @Timed
    @ApiOperation(value = "获取项目的部门和员工树")
    @GetMapping(value = "/m/organization/department")
    public ListResultDTO<WebDepartmentDTO> searchDepartment(@RequestHeader(value = "clientId") UUID projectId) {

        Project project = projectRepository.findById(projectId).get();
        Organization organization = project.getRootOrganization();
        final WebDepartmentDTO department = this.departmentConverter.toTreeDTO(organization);
        return ListResultDTO.success(Lists.newArrayList(department));
    }

    /**
     * 获取部门下的用户列表（员工）
     */
    @Timed
    @ApiOperation(value = "获取部门下的员工列表")
    @GetMapping(value = "/m/user/employee")
    public ListResultDTO<WebUserForListDTO> searchMobileDepartmentEmployee(
            @RequestParam(required = false) UUID departmentId) {

        return this.searchDepartmentEmployee(departmentId);
    }

    /**
     * 获取部门下的用户列表（领导）
     */
    @Timed
    @ApiOperation(value = "获取部门下的部门领导")
    @GetMapping(value = "/m/user/leader")
    public ListResultDTO<WebUserForListDTO> searchDepartmentLeader(
            @RequestParam(required = false) UUID departmentId) {

        if(departmentId == null) {

            UserPrincipal user = CurrentUserContextHolder.getCurrentUser();
            departmentId = user.getOrgId();
        }

        Organization organization = organizationRepository.findById(departmentId)
                .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001003001, Project.class.getSimpleName()));

        // 获取子组织
        List<Organization> organizations = organizationService.getChildrenOrganization(organization);
        organizations.add(organization);

        List<OrganizationEmployeeRole> organizationEmployeeRoles =
                organizationEmployeeRoleRepository.findByOrganizationInAndOrganizationDisableFalseAndRoleCodeIn(
                        organizations, Constant.MANAGER_ROLE_CODES);

        return ListResultDTO.success(userForListConverter.toListDTO(organizationEmployeeRoles.stream()
                .map(l -> l.getOrganizationEmployee().getUser()).collect(Collectors.toSet())));
    }

    /**
     * 获取部门下的用户列表（领导）
     */
    @Timed
    @ApiOperation(value = "获取部门下的部门领导")
    @GetMapping(value = "/m/user/leader/all")
    public ListResultDTO<WebUserForListDTO> searchAllLeader(@RequestHeader(value = "clientId") UUID projectId) {

        List<OrganizationEmployeeRole> organizationEmployeeRoles =
                organizationEmployeeRoleRepository.findByOrganizationProjectIdAndOrganizationDisableFalseAndRoleCodeIn(
                        projectId, Constant.MANAGER_ROLE_CODES);

        return ListResultDTO.success(userForListConverter.toListDTO(organizationEmployeeRoles.stream()
                .map(l -> l.getOrganizationEmployee().getUser()).collect(Collectors.toSet())));
    }
}
